#include "XGLWindowImpl.h"

#include "core/Core.h"
#include "gui/iGraphicsSubsystem.h"
#include "XGraphicsSubsystem.h"

#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/gl.h>

#include <string>
using std::string;

using namespace neiderra::gui;
using namespace neiderra::rendering;
using namespace neiderra::core;

/*XGLWindowImpl::XGLWindowImpl(Core* core, const string& title, aWindow* container): aWindowImpl( core, container )
{
//	XGLWindowImpl( core, title, container, 0, 0, 400, 300 );
}*/

/**
	XGLWindowImpl by default creates doublebuffered RGBA GL window
*/
XGLWindowImpl::XGLWindowImpl(Core* core, const string& title, int x, int y, int w, int h, GUIWindow* container):
		GUIWindowImpl( core, container )
{
	_display = ((XGraphicsSubsystem*)core->getGraphicsSubsystem())->GetDisplay();
	_title = title;
	
	static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
	
	_vi = glXChooseVisual(_display, DefaultScreen(_display), dblBuf);
	
	_cx = glXCreateContext(_display, _vi, None, GL_TRUE);
	
	_cmap = XCreateColormap(_display, RootWindow(_display, _vi->screen), _vi->visual,
						   AllocNone);
	
	_swa.colormap = _cmap;
	_swa.border_pixel = 0;
	_swa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | StructureNotifyMask;
	
	
	_window = XCreateWindow(_display, RootWindow(_display, _vi->screen), x, y, w, h,
						0, _vi->depth, InputOutput, _vi->visual, CWBorderPixel | CWColormap |
								CWEventMask, &_swa);
	
	glXMakeCurrent(_display, _window, _cx);

	XSetStandardProperties(_display, _window, title.c_str(), title.c_str(), None,
						   0, 0, 0);

	
/*	int blackColor = BlackPixel(_display, DefaultScreen(_display));
	int whiteColor = WhitePixel(_display, DefaultScreen(_display));
	
	_gc = XCreateGC(_display, _window, 0, 0);
	
	_window = XCreateSimpleWindow(_display, DefaultRootWindow(_display), 0, 0, 
								  640, 480, 0, blackColor, blackColor);
	
	XSelectInput(_display, _window, StructureNotifyMask);*/
	XGetWindowAttributes( _display, _window, &_attribs );
	
}

XGLWindowImpl::~ XGLWindowImpl()
{
	glXDestroyContext(_display, _cx);
	XDestroyWindow(_display, _window);
//	glXFreeContext(_display, _cx);
	// free _gc
	// free _window
}

int XGLWindowImpl::ResponseEvent( XEvent& e )
{
	switch(e.type)
	{
		case MapNotify:
			
			this->show();
			
			break;
			
		case Expose:
			this->swapBuffers();
			this->update();
			break;
	}	
	return 0;
}

unsigned XGLWindowImpl::getHeight()
{
	
	return _attribs.height;
}

unsigned XGLWindowImpl::getWidth()
{
	return _attribs.width;
}

void XGLWindowImpl::swapBuffers()
{
	glXSwapBuffers(_display, _window);
}

void XGLWindowImpl::setRenderer( iRenderer* r )
{
	_renderer = r;
}

void XGLWindowImpl::show()
{
	XMapWindow(_display, _window);
}

void XGLWindowImpl::update()
{
	glFlush();
}
